\section{C/C++特殊语法}

\subsection{对象大小}
在C语言中，空结构体大小为0，空结构体数组的每个元素都有相同的地址，如果求取数组两个元素的偏移(\verb|&array[1]-&array[0]|),运行时会发生浮点例外。因为会转化为地址差除以元素大小。同理，指针增减操作会转为绝对地址增减乘以元素大小，因此指针位置不会改变。

C++规定任意两个不同对象不可以有相同地址，因此空结构体和空类的实例的大小为1，如果类中只包含一个char成员，对象大小也为1(g++验证)。如果类包含函数(非virtual)，并不会增加对象的大小。如果类包含虚函数，则对象会额外增加4字节的虚指针，以指向虚表。

派生类新增函数，不论是否virtual，均不会增加对象的大小。\cite{pibible}有误。

多重继承的派生类对象的内存布局未被定义，派生类对象地址和某一基类地址数值可能不同，但如果直接比较指针，会发生隐式类型转换，从而比较结果为相等。

\subsection{整数运算}
两个整数作\verb+&&,||,!+逻辑运算只有0和1两种结果。做\verb+&,|,^,~+等位运算，相当于每一bit分别运算,注意取反运算的结果与整数本身的位数有关。

\subsection{压栈顺序}
C标准中未规定参数压栈顺序，但VC和gcc都规定从右往左压栈。如果参数中含有表达式，会从右到左计算完表达式的值，再从右到左压栈。对于形如a++的后自增参数，在计算表达式时创建副本，未来将副本压栈，也相当于在计算表达式之前就将表达式本身压栈了。而形如++a的前自增参数，是将a本身压栈，a的值为所有表达式都计算完成之后时刻的值。
例如，\verb|a=12|，1.\verb|printf("%d, %d\n", ++a, ++a)|,2.\verb|printf("%d, %d\n", ++a, a++)|,3.\verb|printf("%d, %d\n", a++, ++a)|,4.\verb|printf("%d, %d\n", --a, a++)|,5.\verb|printf("%d, %d\n", a--, ++a)|的结果分别为：
\verb|14,14;14,12;13,14;12,12;13,12|。

此外，运算符两侧的两个表达式的计算顺序是未定义的，如\verb|func1()*func2(), if (a[i++]<b[i])|等。

\subsection{自赋值初始化}
\verb+int a = 2; int main() {int a = a;}+的结果是未定义的。


\subsection{强制类型转换}
将浮点数赋值给整数，相当于取整。

\subsection{字符数组长度}
字符数组长度(使用sizeof()求取)等于字符串长度加1, 因为末尾的零也占一位。
而指向字符串的char*变量的长度则为指针长度(比如4)。

这是字符串与字符数组的区别之一。

二者都可以用静态字符串变量初始化。

\subsection{malloc和new的区别}
前者为标准库函数，后者为运算符。前者不在编译器控制权限内，不能自动执行构造函数。new能完成对象初始化工作，delete能完成对象清理工作。

\subsection{指针、引用和句柄}
指针和引用的差别:
\begin{enumerate}
    \item 非空区别。引用不得指向空值
    \item 可修改区别。引用的指向在初始化时确定，永不更改
\end{enumerate}

句柄是32位整数，实际是Windows在内存中维护的一个对象内存物理地址的整数索引，相当于是指向指针的指针。Windows的内存管理经常将当前空闲对象的内存释放掉，当需要访问时再重新提交到物理内存，因此对象的物理地址是变化的，不允许应用程序直接通过物理地址访问对象。

\subsection{异常安全}
一个语句块中的delete语句可能会因抛出异常被被跳过，导致对象未被清理的。\textbf{异常安全}指即使发生异常，程序仍能正确地工作，其中包括资源能够被正确地清理。通过定义一个类来封装资源的分配和释放,可以保证正确释放资源。这一技术常称为“资源分配即初始化”,简称 RAII。

标准库的\verb|auto_ptr|类是的异常安全的“资源分配即初始化”技术的例子(\cite{cppprimer}17.1.9)。\verb|auto_ptr|接受一个类型形参的模板,它为动态分配的对象提供异常安全，在头文件memory中定义。\verb|auto_ptr|被复制或赋值的时候, 有不寻常的行为, 因此, 不能将\verb|auto_ptr|存储在标准库容器类型中。

\begin{lstlisting}
    void f()
    {
	auto_ptr<int> ap(new int(42)); // allocate a new object
	// code that throws an exception that is not caught inside f
    }
    // auto_ptr freed automatically when function ends
\end{lstlisting}



















